#ifndef FND_GAME_2D_ACTOR_MANAGER_HPP
#define FND_GAME_2D_ACTOR_MANAGER_HPP
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/noncopyable.hpp>
#include "drawer.hpp"		// also include message.hpp
#include <string>
#include <utility>
#include <vector>
#include <set>
#include <queue>
#include <map>


namespace sf {
  class RenderWindow ;
    class View ;
    
}
namespace FndGame2D {

  class thinker_manager : public drawer {
  public:
    static const std::string ADD_THINKER ;
    static const std::string REMOVE_THINKER ;
    typedef boost::ptr_map<std::string, FndGame2D::thinker> thinker_ptr_map_type ;
    typedef message<std::string, std::string, std::string> thinker_message_type ;

    typedef std::vector<drawer*> drawer_map_type ;
    typedef thinker_manager class_type ;
    typedef thinker* value_type ;
      
    thinker_ptr_map_type m_thinker_map ;
    //    void update(float time_inteval) ;
    //void render(sf::RenderWindow& app) ;
    thinker* get_thinker(const std::string& name) ;
    bool has_thinker(const std::string& name) ;
    void remove_thinker(const std::string& name, bool must_be_existed = false ) ;
    thinker_manager(sf::RenderWindow& r, const std::string& name = std::string()) ;
  private:
    bool do_handle_message(const thinker_message_type& msg) ;
    bool add_a_thinker(const thinker_message_type& msg) ;
    bool remove_a_thinker(const thinker_message_type& msg) ;
    //void handle_message(const system_message_type& msg) ;
  public:
    //bool do_handle_message(const thinker_message_type& msg) ;
    sf::RenderWindow& system_window() {return m_window ;}
    sf::View* current_render_view() {return m_view ;}
    sf::Vector2f get_mouse_pos_in_render_view(const std::string& view_name =
					      std::string()) const ;
    // uninit
    ~thinker_manager() ;
  private:
    typedef std::pair<std::string, thinker*> manager_add_type ;
    typedef std::vector<manager_add_type> add_thinker_vector_type ;
    typedef std::set<std::string> remove_thinker_set_type ;
    
    bool m_update_guard ;
    add_thinker_vector_type m_safe_add ;
    remove_thinker_set_type m_safe_delete ;
    float m_total_update_time ;
    typedef std::priority_queue<normal_thinker_message_type, std::vector<normal_thinker_message_type>, 
std::greater<normal_thinker_message_type>  > message_queue_type ;
   
    message_queue_type m_message_queue ;
    //system_message_queue_type m_sys_message_queue ;
    sf::View* m_view ;
    sf::RenderWindow& m_window ;
    bool m_is_need_sort ;
    void render_drawers(sf::RenderTarget& w) ;
    void update_thinkers(float time_interval) ;
    bool is_add_thinker_safe() const ;
    bool is_delte_thinker_safe() const ;
    void safe_add_thinker(std::string& name, thinker* thinker_ptr) ;
    void safe_remove_thinker(const std::string& name, bool must_be_existed = false) ;
    bool handle_action_not_care_time(const thinker_message_type& msg) ; 
    void add_thinker(std::string& name, thinker* thinker_ptr) ;
  private:			// control drawer
    drawer_map_type m_drawers ;
  public:
    static const std::string HAS_MANAGER ;
  } ;

}

#endif
